<template>
  <div class="mb-3">
    <label for="exampleFormControlInput1" class="form-label"
      >Email address</label
    >
    <input
      :type="tag"
      class="form-control"
      id="exampleFormControlInput1"
      placeholder="请输入你的内容"
      :class="{ 'is-invalid': error }"
      @blur="handleInputReg"
      :value="value"
      @input="updateValue"
    />
    <span id="emailHelp" v-if="error" class="invalid-feedback">
      {{ message || '请输入信息' }}
    </span>
  </div>
</template>

<script lang="ts">
import { defineComponent, PropType, reactive, toRefs } from 'vue'
import { eventriger } from '@/mitt/index'
import { emailReg, numberReg } from './regs'
import { RuleItemProps } from './types.d'

// 1. 子组件要把事件传递给父组件
// 2. 父组件接收事件，存储事件，执行事件，返回结果

export default defineComponent({
  props: {
    rules: {
      // Array 只能注解外层类型，如果想注解数组内部的值怎么办？
      type: Array as PropType<RuleItemProps[]>
    },
    modelValue: String,
    tag: {
      type: String,
      default: 'text'
    }
  },
  setup(props, context) {
    const inputRef = reactive({
      value: props.modelValue || '',
      error: false,
      message: ''
    })

    const updateValue = (e: KeyboardEvent) => {
      const target = e.target as HTMLInputElement
      inputRef.value = target.value
      context.emit('update:modelValue', target.value)
    }
    // 做每一个input的类型校验
    const handleInputReg = () => {
      if (props.rules) {
        const allPassed = props.rules.every((item) => {
          let itemPass = true
          inputRef.message = item.message
          switch (item.type) {
            // 如果type为required，就是不能为空
            case 'required':
              itemPass = inputRef.value.trim() !== ''
              break
            case 'email':
              itemPass = emailReg.test(inputRef.value.trim())
              break
            case 'number':
              itemPass = numberReg.test(inputRef.value.trim())
              break
          }
          return itemPass
        })
        inputRef.error = !allPassed
        return allPassed
      }
    }

    eventriger.emit('form-item', handleInputReg)

    const { value, error, message } = toRefs(inputRef)
    return {
      updateValue,
      value,
      error,
      message,
      handleInputReg
    }
  }
})
</script>
<style scoped lang="scss">
/* .form-label {
  font-size: 20px;
}
.form-control {
  margin: 10px;
  width: 90%;
  padding: 5px 10px;
  font-size: 12px;
  border-radius: 4px;
} */
</style>
